package com.dc.web.controller;


import com.dc.constant.MessageConstant;
import com.dc.dao.CalibrationPaintHouseChildDao;
import com.dc.dao.CalibrationPaintHouseDao;
import com.dc.dao.ShipDao;
import com.dc.entity.*;
import com.dc.exception.ServiceException;
import com.dc.model.AjaxResult;
import com.dc.model.PageListBody;
import com.dc.utils.DateUtils;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;


@Api(tags = "4-涂装喷漆-0-喷漆房分段喷漆")
@RestController
@RequestMapping("/api/calibration_paint_house")
@Slf4j
public class CalibrationPaintHouseController {

    @Resource
    CalibrationPaintHouseDao calibrationPaintHouseDao;

    @Resource
    CalibrationPaintHouseChildDao calibrationPaintHouseChildDao;

    @Resource
    ShipDao shipDao;

    @GetMapping("/list")
    public AjaxResult list(PageListBody body) {

        Integer pageNumber = body.getPageNumber();
        pageNumber = ObjectUtils.defaultIfNull(pageNumber, 1);
        Integer pageSize = body.getPageSize();
        pageSize = ObjectUtils.defaultIfNull(pageSize, 20);

        PageRequest pageRequest = PageRequest.of(pageNumber - 1, pageSize);
        //calibrationPaintHouseDao.saveAll(calibrationPaintHouseDao.findAll(pageRequest));

        Page<CalibrationPaintHouseEntity> all = calibrationPaintHouseDao.findAll(pageRequest);

        all.getContent().forEach(t-> {
            t.setShipId(t.getShip().getId());
            t.setShipName(t.getShip().getName());
        });

        return AjaxResult.success(all);
    }

    @GetMapping("/{id}")
    public AjaxResult show(@PathVariable("id") Long id) {
        Optional<CalibrationPaintHouseEntity> optional = calibrationPaintHouseDao.findById(id);
        CalibrationPaintHouseEntity entity = null;
        if (optional.isPresent()) {
            entity = optional.get();
            entity.setShipId(entity.getShip().getId());
            entity.setShipName(entity.getShip().getName());
            return AjaxResult.success(entity);
        } else {
            return AjaxResult.error("数据不存在! id = " + id);
        }
    }

    @PostMapping()
    public AjaxResult add(@RequestBody CalibrationPaintHouseEntity entity) {
        entity.setId(null);
        Optional<ShipEntity> optionalShip = shipDao.findById(entity.getShipId());
        if(!optionalShip.isPresent()) {
            throw new ServiceException(MessageConstant.ERR_SHIP_MISSING);
        }
        ShipEntity ship = optionalShip.get();

        entity.setShip(ship);
        // 动态计算
        calc(entity);

        CalibrationPaintHouseEntity save = calibrationPaintHouseDao.save(entity);
        save.setShipName(ship.getName());
        return AjaxResult.success(save);
    }

    @PutMapping("/{id}")
    public AjaxResult update(@PathVariable("id") Long id, @RequestBody CalibrationPaintHouseEntity entity) {

        Optional<CalibrationPaintHouseEntity> optionalRust = calibrationPaintHouseDao.findById(id);
        if(!optionalRust.isPresent()) {
            throw new ServiceException(MessageConstant.ERR_CALIBRATION_MISSION);
        }
        CalibrationPaintHouseEntity paintHouseEntity = optionalRust.get();

        if(!paintHouseEntity.getShip().getId().equals(entity.getShipId())) {      // 如果ship有更换，则更新shipId，否则不更新shipID
            Optional<ShipEntity> optionalShip = shipDao.findById(entity.getShipId());
            if(!optionalShip.isPresent()) {
                throw new ServiceException(MessageConstant.ERR_SHIP_MISSING);
            }
            ShipEntity ship = optionalShip.get();
            paintHouseEntity.setShip(ship);
        }

        //////////// 更新字段
        paintHouseEntity.setArea(entity.getArea());
        paintHouseEntity.setProject(entity.getProject());
        paintHouseEntity.setStartAir(entity.startAir);
        paintHouseEntity.setEndAir(entity.endAir);
        paintHouseEntity.setStartGas(entity.startGas);
        paintHouseEntity.setEndGas(entity.endGas);
        paintHouseEntity.setGasByHour(entity.gasByHour);
        ///////////

        /////////// 动态更新
        calc(paintHouseEntity);
        //////////

        ShipEntity ship = paintHouseEntity.getShip();

        CalibrationPaintHouseEntity save = calibrationPaintHouseDao.save(paintHouseEntity);
        save.setShipId(ship.getId());
        save.setShipName(ship.getName());
        save.getInner().forEach(t -> t.setPid(save.getId()));
        return AjaxResult.success(save);
    }

    @DeleteMapping("/{id}")
    public AjaxResult delete(@PathVariable("id") Long id) {
        Optional<CalibrationPaintHouseEntity> optional = calibrationPaintHouseDao.findById(id);
        if (optional.isPresent()) {
            CalibrationPaintHouseEntity entity = optional.get();
            List<CalibrationPaintHouseChildEntity> inner = entity.getInner();

            if(ObjectUtils.isNotEmpty(inner)) {
                Collection<Long> collect = inner.stream().map(CalibrationPaintHouseChildEntity::getId).collect(Collectors.toList());
                calibrationPaintHouseChildDao.deleteAllById(collect);
            }
            calibrationPaintHouseDao.deleteById(id);

        }
        return AjaxResult.success();
    }

    /////////////////////////////////////// child ////////////////////////////////////////////

    @GetMapping("/child/{id}")
    public AjaxResult showChild(@PathVariable("id") Long id) {
        Optional<CalibrationPaintHouseChildEntity> optional = calibrationPaintHouseChildDao.findById(id);
        CalibrationPaintHouseChildEntity entity = null;
        if (optional.isPresent()) {
            entity = optional.get();
            entity.setPid(entity.getCalibrationPaintHouseEntity().getId());
            return AjaxResult.success(entity);
        } else {
            return AjaxResult.error("数据不存在! id = " + id);
        }
    }

    @PostMapping("/child")
    public AjaxResult addChild(@RequestBody CalibrationPaintHouseChildEntity entity) {
        entity.setId(null);
        Optional<CalibrationPaintHouseEntity> optional = calibrationPaintHouseDao.findById(entity.getPid());

        if(!optional.isPresent()) {
            throw new ServiceException(MessageConstant.ERR_CALIBRATION_MISSION);
        }

        CalibrationPaintHouseEntity calibrationPaintHouseEntity = optional.get();
        entity.setCalibrationPaintHouseEntity(calibrationPaintHouseEntity);
        // 动态计算子
        calcChild(entity);

        CalibrationPaintHouseChildEntity save = calibrationPaintHouseChildDao.save(entity);
        ////////////////////////////////
        // 动态计算
        calibrationPaintHouseEntity.getInner().add(entity);

        calc(calibrationPaintHouseEntity);

        // 查询父，进行计算
        calibrationPaintHouseDao.save(calibrationPaintHouseEntity);

        return AjaxResult.success(save);
    }

    @PutMapping("/child/{id}")
    public AjaxResult updateChild(@PathVariable("id") Long id, @RequestBody CalibrationPaintHouseChildEntity entity) {
        entity.setId(id);
        Optional<CalibrationPaintHouseEntity> optional = calibrationPaintHouseDao.findById(entity.getPid());
        if(!optional.isPresent()) {
            throw new ServiceException(MessageConstant.ERR_CALIBRATION_MISSION);
        }

        CalibrationPaintHouseEntity calibrationPaintHouseEntity = optional.get();
        entity.setCalibrationPaintHouseEntity(calibrationPaintHouseEntity);
        // 动态计算
        calcChild(entity);

        CalibrationPaintHouseChildEntity save = calibrationPaintHouseChildDao.save(entity);
        ///////////////////////////////////////
        // 动态计算
        calc(calibrationPaintHouseEntity);

        // 查询父，进行计算
        calibrationPaintHouseDao.save(calibrationPaintHouseEntity);

        save.setPid(entity.getPid());
        return AjaxResult.success(save);
    }

    @DeleteMapping("/child/{id}")
    public AjaxResult deleteChild(@PathVariable("id") Long id) {
        Optional<CalibrationPaintHouseChildEntity> childEntityOptional = calibrationPaintHouseChildDao.findById(id);
        if(!childEntityOptional.isPresent()) {
            throw new ServiceException(MessageConstant.ERR_CALIBRATION_MISSION);
        }
        CalibrationPaintHouseChildEntity childEntity = childEntityOptional.get();
        CalibrationPaintHouseEntity calibrationPaintHouseEntity = childEntity.getCalibrationPaintHouseEntity();
        calibrationPaintHouseEntity.getInner().remove(childEntity);
        // 动态计算
        calc(calibrationPaintHouseEntity);

        calibrationPaintHouseDao.save(calibrationPaintHouseEntity);

        calibrationPaintHouseChildDao.deleteById(id);
        return AjaxResult.success();
    }

    private CalibrationPaintHouseChildEntity calcChild(CalibrationPaintHouseChildEntity entity) {
        try {
            // 子表计算 powerByHour = (endTime - startTime) * 24 * num * power
            entity.powerByHour = DateUtils.differentDaysDoubleByMillisecond(entity.startTime, entity.endTime) * 24 * entity.num * entity.power;
        } catch (Exception e) {
            entity.powerByHour = 0.;
        }
        return entity;
    }

    private CalibrationPaintHouseEntity calc(CalibrationPaintHouseEntity entity) {

        try {
            // powers;      // 耗电能(kwh) 动态计算
            List<CalibrationPaintHouseChildEntity> inner = entity.getInner();

            double power = inner.stream()
//                .peek(t -> t.powerByHour = DateUtils.differentDaysDoubleByMillisecond(t.startTime, t.endTime) * 24 * t.num * t.power)
                    .mapToDouble(CalibrationPaintHouseChildEntity::getPowerByHour)
                    .reduce(Double::sum)
                    .orElse(0.);
            entity.powers = power;
        } catch (Exception e) {
            entity.powers = 0.;
        }

        // powerByUnit = powers / area
        try {
            entity.powerByUnit = entity.powers / entity.area;
        } catch (Exception e) {
            entity.powerByUnit = 0.;
        }

        // air = endAir - startAir
        try {
            entity.air = entity.endAir - entity.startAir;
        } catch (Exception e) {
            entity.air = 0.;
        }

        // airByUnit = air / area   // 单位用压缩空气量(m³/m²) 动态计算
        try {
            entity.airByUnit = entity.air / entity.area;
        } catch (Exception e) {
            entity.airByUnit = 0.;
        }

        // gas = (endGas - startGas) * gasByHour *24;         // 耗天然气量(m³) 动态计算
        try {
            entity.gas = DateUtils.differentDaysDoubleByMillisecond(entity.startGas, entity.endGas) * entity.gasByHour * 24;
        } catch (Exception e) {
            entity.gas = 0.;
        }

        // gasByUnit = gas / area   单位耗天然气量(m³)  动态计算
        try {
            entity.gasByUnit = entity.gas / entity.area;
        } catch (Exception e) {
            entity.gasByUnit = 0.;
        }

        return entity;
    }

}
